package cn.my.springHDFS.security;

import cn.my.springHDFS.domain.AdminUser;
import cn.my.springHDFS.domain.RoleType;
import cn.my.springHDFS.domain.User;
import cn.my.springHDFS.repository.AdminRepository;
import cn.my.springHDFS.repository.UserRepository;
import cn.my.springHDFS.service.ManagementServiceImpl;
import cn.my.springHDFS.service.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Leo on 2017/4/26.
 */
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private AdminRepository adminRepository;

    @Autowired
    private ManagementServiceImpl managementService;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserServiceImpl userService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String adminAccount = authentication.getName();
        String adminPassword = authentication.getCredentials().toString();
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        if (validateUser(adminAccount, adminPassword, grantedAuthorities, authentication)) {
            Authentication auth = new UsernamePasswordAuthenticationToken(adminAccount, adminPassword, grantedAuthorities);
            return auth;
        } else {
            return null;
        }
    }

    /**
     * 验证所有用户的入口
     * @param adminAccount
     * @param adminPassword
     * @param grantedAuthorities
     * @return
     */
    private boolean validateUser(String adminAccount, String adminPassword, List<GrantedAuthority> grantedAuthorities, Authentication authentication) {
        //管理员实体对象
        AdminUser adminUser = adminRepository.findByAdminAccountAndAdminPassword(adminAccount, adminPassword);

        //用户实体对象
        User user = userRepository.findByAccountAndPassword(adminAccount, adminPassword);

        //HttpServletRequest对象
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        //判断用户类型
        if (validateAdmin(adminUser, adminAccount, adminPassword, grantedAuthorities, httpServletRequest)){
            return true;
        }
        else if (validateCommonUser(user, adminAccount, adminPassword, grantedAuthorities, httpServletRequest)){
            return true;
        }
        return false;
    }

    /**
     * 验证管理员的入口
     * @param adminUser
     * @param adminAccount
     * @param adminPassword
     * @param grantedAuthorities
     * @return
     */
    private boolean validateAdmin(AdminUser adminUser, String adminAccount, String adminPassword, List<GrantedAuthority> grantedAuthorities, HttpServletRequest httpServletRequest){
        if (adminUser == null || adminAccount == null || adminPassword == null){
            return false;
        }
        if (adminUser.getAdminAccount().equals(adminAccount) && adminUser.getAdminPassword().equals(adminPassword) && adminUser.getAdminLoginStatus()){
            if (adminUser.getAdminLevel().equals("ROLE_SUPER")){
                grantedAuthorities.add(new SimpleGrantedAuthority(RoleType.ROLE_SUPER.name()));
                return managementService.adminLoginInfo(adminUser, false, httpServletRequest);
            }
            else if(adminUser.getAdminLevel().equals("ROLE_SECONDADMIN")){
                grantedAuthorities.add(new SimpleGrantedAuthority(RoleType.ROLE_SECONDADMIN.name()));
                return managementService.adminLoginInfo(adminUser, false, httpServletRequest);
            }
            return false;
        }
        return false;
    }

    /**
     * 验证普通用户的入口
     * @param user
     * @param account
     * @param password
     * @param grantedAuthorities
     * @return
     */
    private boolean validateCommonUser(User user, String account, String password, List<GrantedAuthority> grantedAuthorities, HttpServletRequest httpServletRequest){
        if (user == null || account == null || password == null){
            return false;
        }
        if (user.getAccount().equals(account) && user.getPassword().equals(password) && user.getUserLevel().equals("ROLE_USER")){
            grantedAuthorities.add(new SimpleGrantedAuthority(RoleType.ROLE_USER.name()));
            return userService.userLoginInfo(user, false, httpServletRequest);
        }
        return false;
    }


    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}
